﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using Quartz;
using ZHDJ.Core.Log;
using ZHDJ.Data;
using ZHDJ.Data.Models.Common;
using ZHDJ.WinService.Util;
using mas.ecloud.sdkclient;
using mas.ecloud.Model;
using System.Threading;
using ZHDJ.Data.BLL;
using ZHDJ.Data.Models.SMS;
using ZHDJ.Core.Util;

namespace ZHDJ.WinService.Job
{
    public class SmsSendJob : JobBase
    {
        /// <summary>
        /// 执行业务锁
        /// </summary>
        private static Object BusinessLock = new Object();
        private static Client _SMSClient = Client.instance;
        private static bool _SMSLoginState = false;
        private static string _SMSSign = ConfigHelper.SmsSign;
        private Task _GetSubmitReportTask;
        private CancellationTokenSource _GetSubmitReportTaskCancelToken = new CancellationTokenSource();
        private Task _GetStatusReportTask;
        private CancellationTokenSource _GetStatusReportTaskCancelToken = new CancellationTokenSource();
        private string LogFileDebugSuffix = "SmsSend_Debug";
        private string LogFileErrSuffix = "SmsSend_Err";
        private int stateReportNumber = 0;
        private int submitReportNumber = 0;

        public override JobSetInfo JobSetInfo
        {
            get
            { 
                return new JobSetInfo()
                {
                    JobGroup = "SmsSendJobGroup",
                    JobName = "SmsSendJobJob",
                    // 
                    TriggerName = "SmsSendJobTrigger",
                    Cron = ConfigHelper.SmsSendJobIntervalCron
                };
            }
        }

        public override void RunBusiness(IJobExecutionContext context)
        {
            try
            {
                lock (BusinessLock)
                {
                    // 短信发送逻辑代码
                    LogHelper.WriteLog(LogFileDebugSuffix, "短信发送--业务开始");

                    if(!_SMSLoginState)
                        _SMSLoginState = Login();
                    if (!_SMSLoginState)
                        return;

                    // 获取待发送短信
                    DataTable dtSms = SMSHelper.GetSmsSendRecordByNotSend(); 
                    foreach (DataRow dr in dtSms.Rows)
                    {
                        string ID = "";
                        try
                        {
                            // 发送短信
                            ID = dr["ID"].ToString();
                            int smsSendResult = _SMSClient.sendDSMS(new string[] { dr["MobileNo"].ToString() }, dr["SMSContent"].ToString(), "",
                                Convert.ToInt32(dr["SMSPriority"]), _SMSSign, dr["MSGGroup"].ToString());

                            SMSHelper.UpdateSmsSendRecordSendState(ID, smsSendResult);
                        }
                        catch (Exception ex)
                        { LogHelper.WriteLog(LogFileErrSuffix, "短信[" + ID + "]发送异常：" + ex.Message + "\r\n" + ex.StackTrace); }
                    }

                    //获取接收短信
                    var smsReceiveds = _SMSClient.getMO();
                    if (smsReceiveds != null && smsReceiveds.Count > 0) {
                        var smsmorelist = new List<PartySmsmoRecord>();
                        foreach (var item in smsReceiveds)
                        {
                            var morerecord = new PartySmsmoRecord()
                            {
                                AddSerial = item.addSerial,
                                Mobile = item.mobile,
                                Content = item.smsContent,
                                SendTime = item.sendTime,
                                SmsState = 0
                            };
                            smsmorelist.Add(morerecord);
                        }
                        SMSHelper.SaveSMSMoreRecord(smsmorelist);
                    }
                    //MoModel
                }
            }
            catch (Exception ex2)
            {
                LogHelper.WriteLog(LogFileErrSuffix, "短信发送服务异常：" + ex2.Message + "\r\n" + ex2.StackTrace);
            }
        }

        /// <summary>
        /// 服务开始
        /// </summary>
        public override void OnStart()
        {
            LogHelper.WriteLog(LogFileDebugSuffix, "短信发送--启动");
            _SMSLoginState = Login();

            _GetSubmitReportTask = GetSubmitReportAsync(_GetSubmitReportTaskCancelToken.Token);
            _GetStatusReportTask = GetStatusReportAsync(_GetStatusReportTaskCancelToken.Token);
        }

        /// <summary>
        /// 服务停止
        /// </summary>
        public override void OnStop()
        {
            LogHelper.WriteLog(LogFileDebugSuffix, "短信发送--停止");
            _SMSClient.logout();
            SyncSubmitReport();
            SyncStatusReport();
            _SMSLoginState = false;
        } 

        private async Task GetSubmitReportAsync(CancellationToken cancelToken = new CancellationToken())
        {
            while (true)
            {
                try
                {
                    await Task.Factory.StartNew(() =>
                    {
                        SyncSubmitReport();
                    });

                    await Task.Delay(1000 * 10 * 1); // 每10秒钟处理一次
                }
                catch (Exception ex)
                { 
                    LogHelper.WriteLog(LogFileErrSuffix, "同步提交报告线程异常：" + ex.Message + "；" + ex.StackTrace);
                    await Task.Delay(1000 * 30);     //异常时30秒后重试
                }
            }
        }
        private async Task GetStatusReportAsync(CancellationToken cancelToken = new CancellationToken())
        {
            while (true)
            {
                try
                {
                    await Task.Factory.StartNew(() =>
                    {
                        SyncStatusReport();
                    });

                    await Task.Delay(1000 * 10 * 1); // 每10秒钟处理一次
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(LogFileErrSuffix, "同步状态报告线程异常：" + ex.Message + "；" + ex.StackTrace);
                    await Task.Delay(1000 * 30);     //异常时30秒后重试
                }
            }
        }
         

        private bool Login()
        {
            bool loginResout = _SMSClient.login(ConfigHelper.SmsUrl, ConfigHelper.UserAccount, ConfigHelper.SmsPassword, ConfigHelper.SmsECName);

            LogHelper.WriteLog(LogFileDebugSuffix, string.Format("登录--URL:{0};UserAccount:{1};ECName:{2};loginResout:{3}",
                                            ConfigHelper.SmsUrl, ConfigHelper.UserAccount, ConfigHelper.SmsECName, loginResout));
            return loginResout;
        }

        private void SyncSubmitReport()
        {
            LogHelper.WriteLog(LogFileDebugSuffix + "_Report", "SyncSubmitReport" + (submitReportNumber++).ToString());
            List<SMSSubmitReport> listSMSSubmitReport = GetSubmitReport();
            foreach(SMSSubmitReport item in listSMSSubmitReport)
            {
                try
                {
                    int updateSmsNum = SMSHelper.UpdateSmsSendRecordSubmitReportsState(item.MsgGroup, item.Mobile, item.ReportStatus);
                    SMSHelper.SaveSMSSubmitReport(item, updateSmsNum);
                }
                catch(Exception ex)
                {
                    LogHelper.WriteLog(LogFileErrSuffix, string.Format("同步提交报告异常[{0},{1},{2},{3},{4},{5},{6},{7}]：", 
                        item.ErrorCode, item.ID, item.Mobile, item.MsgGroup, item.ReceiveDate,
                        item.Remark, item.ReportStatus, item.SubmitDate) + ex.Message + "；" + ex.StackTrace);
                }
            }
        }

        private void SyncStatusReport()
        {
            LogHelper.WriteLog(LogFileDebugSuffix + "_Report", "SyncStatusReport" + (stateReportNumber++).ToString());
            List<SMSStatusReport> listSMSStatusReport = GetStatusReport();
            foreach (SMSStatusReport item in listSMSStatusReport)
            {
                try
                {
                    int updateSmsNum = SMSHelper.UpdateSmsSendRecordStatusReportsState(item.MsgGroup, item.Mobile, item.ReportStatus);
                    SMSHelper.SaveSMSStatusReport(item, updateSmsNum);
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(LogFileErrSuffix, string.Format("同步状态报告异常[{0},{1},{2},{3},{4},{5},{6},{7}]：",
                        item.ErrorCode, item.ID, item.Mobile, item.MsgGroup, item.ReceiveDate,
                        item.Remark, item.ReportStatus, item.SubmitDate) + ex.Message + "；" + ex.StackTrace);
                }
            }
        }

        private List<SMSSubmitReport> GetSubmitReport()
        {
            List<SMSSubmitReport> listSMSSubmitReport = new List<SMSSubmitReport>();
            List<SubmitReportModel> listSubmitReportModel = _SMSClient.getSubmitReport();
            foreach (SubmitReportModel model in listSubmitReportModel)
            {
                if(model.mobiles == null)
                    model.mobiles = new string[]{ ""};
                string remark = (model.mobiles.Length > 1 ? StringHelper.NewID : "");

                foreach (string mobile in model.mobiles)
                {
                    listSMSSubmitReport.Add(new SMSSubmitReport()
                    {
                        ErrorCode = model.errorCode,
                        ID = StringHelper.NewID,
                        Mobile = mobile,
                        MsgGroup = model.msgGroup,
                        ReceiveDate = model.receiveDate,
                        Remark = remark,
                        ReportStatus = model.reportStatus,
                        SubmitDate = model.submitDate
                    });
                }
            }

            return listSMSSubmitReport;
        }

        private List<SMSStatusReport> GetStatusReport()
        {
            List<SMSStatusReport> listSMSStatusReport = new List<SMSStatusReport>();
            List<StatusReportModel> listStatusReportModel = _SMSClient.getReport();

            foreach(StatusReportModel model in listStatusReportModel)
            {
                listSMSStatusReport.Add(new SMSStatusReport()
                {
                    ErrorCode = model.errorCode,
                    ID = StringHelper.NewID,
                    Mobile = model.mobile,
                    MsgGroup = model.msgGroup,
                    ReceiveDate = model.receiveDate,
                    Remark = "",
                    ReportStatus = model.reportStatus,
                    SubmitDate = model.submitDate 
                });
            }

            return listSMSStatusReport;
        }
    }
}
